﻿using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using DataManageSystem.Data;
using DataManageSystem.Models;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using StackExchange.Redis;

namespace DataManageSystem.Services.backservices
{
    public class DataCollectBackService : BackgroundService
    {
        private readonly IServiceScopeFactory _scopeFactory;
        private readonly ILogger<DataCollectBackService> _logger;
        private readonly IDatabase _redisDb;

        private const string RedisKey = "DataCollect:LastNotifyTime";

        public DataCollectBackService(
            IServiceScopeFactory scopeFactory,
            ILogger<DataCollectBackService> logger,
            IConnectionMultiplexer redis
        )
        {
            _scopeFactory = scopeFactory;
            _logger = logger;
            _redisDb = redis.GetDatabase(14); // 使用 Redis 的第 14 个数据库
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            _logger.LogInformation("后台数据检测服务启动...");

            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    using var scope = _scopeFactory.CreateScope();
                    var dbContext = scope.ServiceProvider.GetRequiredService<DeviceDbContext>();
                    var mailService = scope.ServiceProvider.GetRequiredService<IMailService>();

                    var latestRecord = dbContext
                        .TAttributeRecords.Where(r => r.CreateTime != null)
                        .OrderByDescending(r => r.CreateTime)
                        .FirstOrDefault();
                    if (latestRecord?.CreateTime != null)
                    {
                        var now = DateTime.Now;
                        var diff = now - latestRecord.CreateTime.Value;

                        if (diff.TotalHours > 2)
                        {
                            var lastNotifyStr = await _redisDb.StringGetAsync(RedisKey);
                            DateTime? lastNotifyTime = null;

                            if (
                                lastNotifyStr.HasValue
                                && DateTime.TryParse(lastNotifyStr, out var parsed)
                            )
                                lastNotifyTime = parsed;

                            if (
                                !lastNotifyTime.HasValue
                                || (now - lastNotifyTime.Value).TotalHours >= 1
                            )
                            {
                                _logger.LogWarning(
                                    $"数据超过2小时未更新，最后时间为：{latestRecord.CreateTime:yyyy-MM-dd HH:mm:ss}"
                                );

                                var mailRequest = new MailRequest
                                {
                                    To = "zhzhh@modelinglab.ai",
                                    Subject = "【长光所系统告警】数据未更新超时",
                                    Body =
                                        $"系统检测到长光所环境数据采集服务在 {latestRecord.CreateTime:yyyy-MM-dd HH:mm:ss} 后超过 2 小时未更新，请尽快检查数据采集服务。",
                                };

                                await mailService.SendEmailAsync(mailRequest);

                                // 存入 Redis，防止短时间内重复发送
                                await _redisDb.StringSetAsync(RedisKey, now.ToString("o")); // ISO 8601 格式
                            }
                        }
                        else
                        {
                            // 数据正常，清理 Redis 标记
                            await _redisDb.KeyDeleteAsync(RedisKey);
                        }
                    }
                    else
                    {
                        _logger.LogWarning("未找到任何记录或记录无创建时间。");
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "数据检测过程中发生异常");
                }

                await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken); // 每 5 分钟轮询一次
            }

            _logger.LogInformation("DataCollectBackService 停止");
        }
    }
}
